#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <time.h>
#include <unistd.h>
#include "srtp.h"

// Initialize spcb
struct srtp_server_pcb f;

// sockaddr_in for listen_info
struct sockaddr_in listen_info;

// sockaddr_in for client_info
struct sockaddr_in client_info;

// Initializes the server components
int server_port_num;
int socket_server;

// Temporary buffer for data to receive/send
char buffer[SRTP_MAX_PAYLOAD_SIZE];
char str[SRTP_MAX_PAYLOAD_SIZE];

// create datagram to store received info  
ssize_t datagram;

// Initialize a socket for the client
socklen_t fSockLen;



main(int argc, char *argv[]){
    if (argc != 2) {
        
        printf("Usage: \n %s <port>\n", argv[0]);
        
    } else {
        
        server_port_num = atoi(argv[1]);
        
        // Acting as a proxy
        
        printf(">> This is the Test proxy...\n");
        srtp_server_proxy_listen(&f, server_port_num);
        
    }
}

int srtp_server_proxy_listen(struct srtp_server_pcb *spcb, int port){
    
    // Set listen_info details
    listen_info.sin_family = AF_INET;
    listen_info.sin_addr.s_addr = INADDR_ANY; 
    listen_info.sin_port = htons(f.server_port_num_pcb);
    bzero(&(listen_info.sin_zero),8);
    fSockLen = sizeof(listen_info);
    
    // Create a socket 
    socket_server = socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP);
    
    // Send info to spcb
    f.sockfd = socket_server;
    printf("The socket is  %d\n",socket_server);
    
    int bind_call;
    bind_call = bind(f.sockfd,(struct sockaddr*)&listen_info, sizeof(struct sockaddr));
    if (bind_call < 0){
        perror("|| On bind");
    }
    for(;;){
        // Receiving
        printf ("Waiting for datagram....\n");
        // Calls srtp_accept to accept the connection
        srtp_server_proxy_accept(&f);
    }  
    
}

int srtp_server_proxy_accept(struct srtp_server_pcb *spcb){
    
    // Create buffer to store things
    struct pktbuf temp;
    
    // Create serv_hdr to store header info
    struct srtp_hdr serv_hdr; 
    
    // Create ack_packet
    struct pktbuf ack_packet;
    
    // Create receiving header
    struct srtp_hdr rec_hdr;
    
    // Create an ack_packet for receiving
    struct pktbuf ack_packet_rec; 
     
    // Creating header for the syn packet 
    serv_hdr.type = 2;
    serv_hdr.seqnbr = 0;
    
    // Filling in syn packet with info
    ack_packet.serv_hdr = serv_hdr;
    // ack_packet_rec.serv_hdr.seqnbr = 1;
    // not sending anything
    ack_packet.len = 0;
    ack_packet.payload[0];
    int z = 0;
    if(z%3 != 0){
        struct timeval tv;
        //waiting for 3 seconds
        tv.tv_sec = 3;
        tv.tv_usec = 0;
        
        fd_set readfds, masterfds;
        
        FD_ZERO(&masterfds);
        FD_SET(f.sockfd, &masterfds);
        
        memcpy(&readfds, &masterfds, sizeof(fd_set));
        printf(">> Waiting......\n");
        if (select(f.sockfd+1, &readfds, NULL, NULL, &tv) < 0) {
            perror("|| On SRTP_ACCEPT Select");
            exit(1);
        }
        
        if (FD_ISSET(f.sockfd, &readfds)) {
            //setting datagram = info received
            datagram = recvfrom(f.sockfd, (struct pktbuf *)&temp,SRTP_MAX_PAYLOAD_SIZE+20, 0, (struct sockaddr *)&client_info, &fSockLen);
            z++;
            if (datagram == -1) {
                //check for error
                perror("|| On SRTP_ACCEPT recvfrom");
                exit(EXIT_FAILURE);
            }
        }      
    }
    else if(z % 5 !=0){
        temp.payload == 0;
    }
    else{
        datagram = recvfrom(f.sockfd, (struct pktbuf *)&temp,SRTP_MAX_PAYLOAD_SIZE+20, 0, (struct sockaddr *)&client_info, &fSockLen);
    }
    
    printf(">> Data received!!!... \n");
    
    int send_data = sendto(f.sockfd, &temp, sizeof(struct pktbuf), 0,(struct sockaddr *)&client_info, sizeof(client_info));
    
    printf(">> Data forwarded!!!... \n");
    
    
}
